﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Fasterflect;

namespace RedisDemos.Extensions
{
    public static class ObjectExtensions
    {
        public static Byte[] Dump<T>(this T actual) where T : struct
        {
            return Encoding.UTF8.GetBytes(actual.ToString());
        }

        public static Byte[] Dump(this Object actual)
        {
            if (actual == null)
                return new Byte[0];
            return Encoding.UTF8.GetBytes(actual.ToString());
        }

        public static String AsString(this Byte[] actual)
        {
            if (actual == null)
                return String.Empty;
            return Encoding.UTF8.GetString(actual);
        }

        public static Int64 AsInt64(this Byte[] actual)
        {
            if (actual == null)
                return -1;
            return Int64.Parse(actual.AsString());
        }

        public static Object ChangeType(this String actual, Type conversionType)
        {
            return Convert.ChangeType(actual, conversionType);
        }

        public static Dictionary<String, Byte[]> AsHash(this Object actual)
        {
            return actual.GetType()
                         .Properties()
                         .ToDictionary(p => p.Name, p => actual.GetPropertyValue(p.Name).Dump());
        }

        public static T AsObject<T>(this Dictionary<String, Byte[]> actual) where T : class, new()
        {
            var result = new T();
            var properties = typeof(T).Properties().Where(p => actual.ContainsKey(p.Name));
            var propertiesTypes = properties.ToDictionary(p => p.Name, p => p.Type());
            foreach (var property in properties)
                result.SetPropertyValue(property.Name,
                                        actual[property.Name].AsString().ChangeType(propertiesTypes[property.Name]));
            return result;
        }
    }
}